package com.feinno.urcs.group.http.task;

import com.feinno.sip.header.ContentType;
import com.feinno.sip.header.Event;
import com.feinno.sip.message.SipResponse;
import com.feinno.sip.transaction.TransactionClient;
import com.feinno.sip.transaction.TransactionClientListener;
import com.feinno.urcs.group.GroupConfiguration;
import com.feinno.urcs.group.GroupConstants;
import com.feinno.urcs.group.entity.GroupInfo;
import com.feinno.urcs.group.entity.GroupMember;
import com.feinno.urcs.group.entity.GroupMemberStatus;
import com.feinno.urcs.group.http.config.GroupHttpConstant;
import com.feinno.urcs.group.http.util.StringHelper;
import com.feinno.urcs.group.pd.task.entity.PdGroupInfoNotifyArgs;
import com.feinno.urcs.group.pd.upstream.entity.*;
import com.feinno.urcs.sip.UrcsSipFactory;
import com.feinno.urcs.sipservlet.SipServletFuture;
import com.feinno.urcs.sipservlet.SipServletRequest;
import org.helium.framework.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.sip.address.SipURI;
import javax.sip.header.ContentTypeHeader;
import javax.sip.header.EventHeader;
import javax.xml.stream.XMLStreamException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by wuzhiguo on 15-6-5.
 */
public class PdGroupInfoNotifyTask extends PdBaseNotifyTask implements Task<PdGroupInfoNotifyArgs> {

    private static final Logger LOGGER = LoggerFactory.getLogger(PdGroupInfoNotifyTask.class);

    @Override
    public void processTask(PdGroupInfoNotifyArgs args) {
        try {
            if (LOGGER.isInfoEnabled()) {
                LOGGER.info(String.format("Received Args: %s", args));
            }

            byte[] content = createContentXml(args);
            SipServletRequest request = createSipRequest(args.getBaseGroupNotify(), content);

            // 首次订阅下发群全量信息，调整Sip头
            request.removeHeader(EventHeader.NAME);
            request.removeHeader(ContentTypeHeader.NAME);
            Event event = new Event();
            event.setEventType("group");
            request.setHeader(event);
            request.setHeader(new ContentType("application", "public-group+xml"));

            // todo 查文档看看版本号放哪里？


            if (LOGGER.isInfoEnabled()) {
                LOGGER.info(String.format("Create SipRequest: %s", request.toString()));
            }

            SipServletFuture future = request.sendRequest();
            future.setListener(new TransactionClientListener() {
                @Override
                public void onTransProvisionalResponse(TransactionClient tc, SipResponse response) {
                    if (LOGGER.isInfoEnabled()) {
                        LOGGER.info(String.format("Received SipResponse: %s", response.toString()));
                    }
                }

                @Override
                public void onTransSuccessResponse(TransactionClient tc, SipResponse response) {
                    if (LOGGER.isInfoEnabled()) {
                        LOGGER.info(String.format("Received SipResponse: %s", response.toString()));
                    }
                }

                @Override
                public void onTransFailureResponse(TransactionClient tc, SipResponse response) {
                    LOGGER.error(String.format("Trans Failure.\n " +
                                    "SipRequest: %s\n " +
                                    "SipResponse: %s",
                            request.toString(),
                            response.toString()));
                }

                @Override
                public void onTransTimeout(TransactionClient tc) {
                    LOGGER.error(String.format("Trans Timeout. SipRequest: %s", request.toString()));
                }
            });

        } catch (Exception ex) {
            LOGGER.error(String.format("process() Error. Received Args: %s", args), ex);
        }
    }

    private byte[] createContentXml(PdGroupInfoNotifyArgs args) throws XMLStreamException, ParseException {
        GroupInfo groupInfo = args.getGroupInfo();
        String groupUri = groupInfo.getGroupIndex().getConferenceUri();
        String groupAdmin = groupInfo.getGroupAdmin().toString();

        PublicGroup publicGroup = new PublicGroup();
        PublicGroup_List list = new PublicGroup_List();
        PublicGroup_MetaData metaData = new PublicGroup_MetaData();
        publicGroup.setList(list);
        publicGroup.setMetaData(metaData);

        list.setName(groupInfo.getSubject());
        list.setUri(groupUri);
        list.setMax(String.valueOf(groupInfo.getLimitMemberCount()));

        List<PublicGroup_List_Entry> entryList = new ArrayList<>();
        list.setEntryList(entryList);

        if (groupInfo.getMembers() != null && groupInfo.getMembers().size() > 0) {
            for (int i = 0; i < groupInfo.getMembers().size(); i++) {
                GroupMember member = groupInfo.getMembers().get(i);
                PublicGroup_List_Entry entry = new PublicGroup_List_Entry();
                entryList.add(entry);

                SipURI memberSipURL = UrcsSipFactory.getAddressFactory().createSipURI(member.getMobileNo().toString(), GroupConfiguration.INSTANCE.getDomain());
                entry.setUri(memberSipURL.toString());

                // 只有PENDING状态是等待同意，其他都是正式群成员
                if (member.getStatus() == GroupMemberStatus.PENDING) {
                    entry.setStatus("pending");
                } else {
                    entry.setStatus("active");
                }

                if (member.getMobileNo().equals(groupAdmin)) {
                    entry.setOwner("true");
                }

                entry.setDisplayName(new PublicGroup_List_Entry_DisplayName(member.getDisplayname()));
            }
        }

        SipURI creatorSipURL = UrcsSipFactory.getAddressFactory().createSipURI(groupAdmin, GroupConfiguration.INSTANCE.getDomain());
        metaData.setCreator(new PublicGroup_MetaData_Creator(creatorSipURL.toString()));
        metaData.setIdentifier(new PublicGroup_MetaData_Identifier(String.format(GroupConstants.PUBLIC_GROUP_IDENTIFIER_TEMPLATE, groupUri)));
        metaData.setTimestamp(new PublicGroup_MetaData_Timestamp(StringHelper.generateXmlDateFormatString(groupInfo.getCreateTime())));
        metaData.setNeedPermit(new PublicGroup_MetaData_NeedPermit("false"));

        return publicGroup.toXmlByteArray();
    }
}
